<!--
 * @Author: xjt
 * @Date: 2020-12-09 11:28:58
 * @LastEditTime: 2021-04-28 18:01:12
 * @Description: 付款登记弹窗组件，支持新增、编辑、查看
-->
<template>
  <div class="addDialog" :class="{previewPage: isReadonly}">
    <el-dialog :close-on-click-modal="false" :title="dialogTitle" :visible.sync="dialogVisible" width="1200px" @close="handleClosed" class="basic-form">
      <div class="dialogWrap">
        <el-form ref="dialogForm" :rules="rules" :model="formData" class="form-wrap">
          <h4 class="dialogItemTitle full">基本信息</h4>
          <div class="listFormItem">
            <el-button class="add" size="mini" type="primary" @click="$refs.chooseDialog.show()" v-if="type === 'add'">选择合同</el-button>
            <el-form-item label="合同编号" prop="contractNo">
              <el-input v-halfCharCode v-model="formData.contractNo" maxlength="20" readonly placeholder="请选择合同编号" />
            </el-form-item>
          </div>
          <el-form-item label="合同类型" prop="contractType">
            <el-select clearable v-model="formData.contractType" placeholder="请选择合同类型" disabled>
              <el-option v-for="item in contractTypes" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="物业名称" prop="propertyName">
            <el-input v-halfCharCode v-model="formData.propertyName" maxlength="20" disabled placeholder="请输入物业名称" />
          </el-form-item>
          <div class="listFormItem">
            <el-form-item label="乙方单位名称" prop="unitName">
              <el-input v-halfCharCode v-model="formData.unitName" maxlength="20" disabled placeholder="请选择合同乙方" />
            </el-form-item>
          </div>
          <el-form-item label="合同签订日期" prop="signingDate">
            <el-date-picker v-model="formData.signingDate" value-format="yyyy-MM-dd" format="yyyy-MM-dd" placeholder="请选择签订日期" disabled />
          </el-form-item>
          <el-form-item label="合同金额(元)" prop="contractAmount">
            <el-input :value="formData.contractAmount | thousandMoney" maxlength="20" disabled placeholder="请输入合同金额(元)" />
          </el-form-item>
          <el-form-item label="付款方式" prop="paymentType">
            <el-select clearable v-model="formData.paymentType" placeholder="请选择付款方式" disabled>
              <el-option v-for="item in paymentWays" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>

          <h4 class="dialogItemTitle full">本次付款信息</h4>
          <el-form-item label="付款项目" prop="paymentProject">
            <el-select clearable v-model="formData.paymentProject" placeholder="请选择付款项目" :disabled="isReadonly">
              <el-option v-for="item in paymentProjects" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="付款次数" prop="paymentNum">
            <el-input v-halfCharCode v-model="formData.paymentNum" :readonly="isReadonly" disabled maxlength="3" />
          </el-form-item>
          <el-form-item label="付款日期" prop="paymentDate">
            <el-date-picker v-model="formData.paymentDate" value-format="yyyy-MM-dd" format="yyyy-MM-dd" placeholder="请选择付款日期" :readonly="isReadonly" />
          </el-form-item>
          <el-form-item label="付款金额(元)" prop="paymentAmount">
            <el-input v-halfCharCode v-model="formData.paymentAmount" v-if="!isReadonly" :disabled="formData.paymentType !== '5'" maxlength="15" />
            <el-input :value="formData.paymentAmount | thousandMoney" v-else disabled />
          </el-form-item>
          <el-form-item label="备注" prop="remarks" class="full">
            <el-input v-halfCharCode v-model="formData.remarks" type="textarea" :readonly="isReadonly" :placeholder="isReadonly ? '暂无内容' : '请输入内容'" maxlength="200" />
          </el-form-item>

          <div class="full" v-if="formData.hisPaymentContractRegistrationList && formData.hisPaymentContractRegistrationList.length">
            <h4 class="dialogItemTitle">历史付款信息</h4>
            <el-table align="left" :data="formData.hisPaymentContractRegistrationList">
              <el-table-column label="付款项目" prop="paymentProject" :formatter="paymentFormatter" />
              <el-table-column label="付款次数" prop="paymentNum" :formatter="paymentFormatter" />
              <el-table-column label="付款金额" prop="paymentAmount" :formatter="priceFormatter" />
              <el-table-column label="付款日期" prop="paymentDate" :formatter="paymentFormatter" />
            </el-table>
          </div>

          <!-- 附件 -->
          <div class="full" v-if="dialogVisible">
            <div v-if="oldFiles.length || type !== 'preview'">
              <h4 class="dialogItemTitle">上传附件</h4>
            </div>
            <v-upload
              ref="upload"
              :busId="formData.paymentRegistrationId"
              modelType="singlePayment"
              @onSuccess="onSuccess"
              @loadCompleted="handleLoadCompleted"
              v-model="uploadFileList"
              :isView="['preview'].includes(type)"
              :canDelete="['add','edit'].includes(type)"
            />
          </div>
        </el-form>

        <!-- 选择弹窗 -->
        <choose-dialog ref="chooseDialog" v-bind="chooseDialogAttrs" :disabledArr="disabledArr" @loadCompleted="handleContractLoadCompleted" @chooseData="handleChoose" />
      </div>
      <div slot="footer">
        <el-button @click="$bus.$emit('operationLog',formData.paymentContractId)" v-if="type==='preview'">操作日志</el-button>
        <el-button v-if="type !== 'preview'" type="primary" v-throttle="[save]">提 交</el-button>
        <el-button @click="dialogVisible = false">关闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { editPayment, getPaymentHistory, getPaymentById } from "@/views/wy-operate/api/payment";
import { getDict } from '@/utils'
export default {
  name: "paymentDialog",
  inject: ['initList'],
  data () {
    return {
      //弹窗类型，默认新增
      type: "add",
      //弹窗开关
      dialogVisible: false,
      // 表单项
      formData: {
        // 合同金额
        contractAmount: 0,
        // 剩余付款总金额
        sumContractAmountRemaining: 0,
        // 合同编号
        contractNo: "",
        // 合同类型
        contractType: "",
        // 付款金额
        paymentAmount: 0,
        // 付款合同id
        paymentContractId: "",
        // 历史记录
        hisPaymentContractRegistrationList: [],
        // 付款日期
        paymentDate: "",
        // 付款次数
        paymentNum: 0,
        // 付款项目
        paymentProject: "",
        // 主键id
        paymentRegistrationId: "",
        // 付款方式
        paymentType: "",
        // 物业名称
        propertyName: "",
        // 备注
        remarks: "",
        // 签订日期
        signingDate: "",
        // 单位名称
        unitName: ""
      },
      // 暂存的付款金额
      cachePaymentAmount: 0,
      // 上传文件列表
      uploadFileList: [],
      // 已上传的文件
      oldFiles: [],
      // 禁止选择的合同数据
      disabledArr: [],
      // 校验
      rules: {
        contractNo: [{ required: true, message: "合同编号不能为空", trigger: "blur" }],
        contractType: [{ required: true, message: "合同类型不能为空", trigger: "blur" }],
        propertyName: [{ required: true, message: "物业名称不能为空", trigger: "blur" }],
        unitName: [{ required: true, message: "乙方单位不能为空", trigger: "blur" }],
        signingDate: [{ required: true, message: "合同签订日期不能为空", trigger: "blur" }],
        contractAmount: [{ required: true, message: "合同金额不能为空", trigger: "blur" }],
        paymentType: [{ required: true, message: "付款方式不能为空", trigger: "blur" }],
        paymentType: [{ required: true, message: "付款方式不能为空", trigger: "blur" }],
        paymentProject: [{ required: true, message: "付款项目不能为空", trigger: "blur" }],
        paymentDate: [{ required: true, message: "付款日期不能为空", trigger: "blur" }],
        paymentAmount: [
          { required: true, message: "付款金额不能为空", trigger: "blur" },
          { validator: this.paymentAmountValidator, trigger: 'blur' },
        ],
      },
    };
  },
  computed: {
    // 弹窗标题计算
    dialogTitle () {
      return {
        preview: "查看",
        edit: "编辑",
        add: "新增"
      }[this.type];
    },
    // 判断是否只读
    isReadonly () {
      return ["preview"].includes(this.type);
    },
    // 合同类型
    contractTypes () {
      return getDict('payment-contract-type')
    },
    // 付款方式
    paymentWays () {
      return getDict('payment-contract-pay-way')
    },
    // 付款项目
    paymentProjects () {
      return getDict('payment-contract-pay-project')
    },
    // 选择弹窗属性数据
    chooseDialogAttrs () {
      const contractTypeFormatter = (row, column, cellValue) => {
        if (this.contractTypes.length === 0) return '';
        let type = this.contractTypes.find(item => item.value == cellValue)
        return type ? type.label : '';
      }
      return {
        title: '选择合同',
        placeholder: '请输入物业名称',
        url: '/api/payment/contract/page',
        primaryKey: 'paymentContractId',
        width: "1000px",
        showData: [
          { prop: 'contractNo', label: '合同编号', width: '200', align: 'center' },
          { prop: 'contractType', label: '合同类型', width: '200', align: 'center', formatter: contractTypeFormatter },
          { prop: 'propertyName', label: '物业名称', width: '200', align: 'center' },
          { prop: 'unitName', label: '乙方单位名称', width: '200', align: 'center' },
        ],
        returnData: ['contractAmount', 'contractNo', 'contractType', 'paymentContractId', 'paymentType', 'signingDate', 'unitName', 'propertyName', 'sumPaymentAmount']
      }
    }
  },
  methods: {
    //开启弹窗
    show ({ type, data = {} }) {
      if (['preview', 'edit'].includes(type)) {
        this.formData.paymentRegistrationId = data.paymentRegistrationId;
        getPaymentById(data.paymentRegistrationId).then(res => {
          let info = res.data.data;
          this.formData = { ...this.formData, ...data };
          if (type === 'edit') {
            //单独存一份付款金额，用于编辑金额时校验金额
            this.cachePaymentAmount = data.paymentAmount
          }
          this.getPaymentHistory(data.paymentContractId)
        })
      }

      this.type = type;
      this.dialogVisible = true;
    },
    // 提交新增
    save () {
      if (['edit', 'add'].includes(this.type)) {
        this.$refs.dialogForm.validate(validate => {
          validate && this.$refs.upload.submit();
        })
      }
    },
    // 上传成功
    async onSuccess (response, file, fileList) {
      let params = this.type == 'add' ? { ...this.formData, paymentRegistrationId: response.data } : JSON.parse(JSON.stringify(this.formData))
      const res = await editPayment(params, this.type)
      if (res.data.code == 0) {
        this.$message.success(`${this.dialogTitle}成功!`);
        this.initList({ keyword: '', current: 1 })
        this.dialogVisible = false;
      } else {
        this.$message.error(res.data.msg)
      }
    },
    // 弹窗关闭还原
    handleClosed () {
      this.uploadFileList = []
      this.disabledArr = []
      this.cachePaymentAmount = 0
      this.formData = {
        contractAmount: 0,
        sumContractAmountRemaining: 0,
        contractNo: "",
        contractType: "",
        paymentAmount: 0,
        paymentContractId: "",
        hisPaymentContractRegistrationList: [],
        paymentDate: "",
        paymentNum: 0,
        paymentProject: "",
        paymentRegistrationId: "",
        paymentType: "",
        propertyName: "",
        remarks: "",
        signingDate: "",
        unitName: ""
      }
      this.$refs.dialogForm.resetFields();
    },
    // 监听上传组件上传完成
    handleLoadCompleted (data) {
      this.oldFiles = data
    },
    // 监听弹窗选中
    handleChoose (data) {
      let formData = { ...this.formData, ...data }
      // 一次性付款直接把付款金额加进去
      if (data.paymentType == '0') {
        formData.paymentAmount = data.contractAmount
      }
      // 新增场景获取付款记录
      if (this.type == 'add') {
        this.getPaymentHistory(data.paymentContractId)
      }
      this.formData = formData
    },
    // 获取付款记录
    async getPaymentHistory (id) {
      const res = await getPaymentHistory(id)
      const { hisPaymentContractRegistrationList = [], sumRemainingAmount } = res.data.data
      console.log(hisPaymentContractRegistrationList)
      if (this.type === 'add') {
        this.formData.paymentNum = hisPaymentContractRegistrationList.length && this.formData.paymentType === '5' ? hisPaymentContractRegistrationList.length + 1 : 1;
      }
      this.formData.hisPaymentContractRegistrationList = hisPaymentContractRegistrationList
      this.formData.sumRemainingAmount = sumRemainingAmount
    },
    // 校验合同编号是否重复
    handleContractNoRepeat (rule, value, callback) {
      let params = { contractNo: value }
      if (this.type === 'edit') {
        params.paymentContractId = this.formData.paymentContractId
      }
      checkContractNo(params, this.type).then(res => {
        if (res.data.code == 0 && res.data.data) {
          return callback()
        }
        return callback(new Error('合同编号不能重复'))
      })
    },
    // 格式化付款项目
    paymentFormatter (row, column, cellValue) {
      switch (column.property) {
        case 'paymentDate': // 付款日期
          return cellValue ? cellValue.split(' ')[0] : '';
        case 'paymentProject': // 付款项目
          let type = this.contractTypes.find(item => item.value == cellValue)
          return type ? type.label : '';
        case 'paymentNum': // 付款次数
          return `第 ${cellValue} 次`
        default:
          break;
      }
    },
    // 付款金额校验
    paymentAmountValidator (rule, value, callback) {
      if (Number(value) <= 0) {
        return callback(new Error('付款金额必须大于0'))
      }
      if (this.formData.paymentNum <= 1) {
        if (value > this.formData.contractAmount) {
          return callback(new Error('付款金额不能超过合同金额'))
        }
      } else {
        // 判断场景，如果是编辑场景，要忽略掉本身的值
        console.log(value, this.formData.sumRemainingAmount, this.cachePaymentAmount)
        let sumContractAmountRemaining = this.type === 'add' ? this.formData.sumRemainingAmount : this.formData.sumRemainingAmount + this.cachePaymentAmount
        if (value > sumContractAmountRemaining) {
          return callback(new Error('付款金额不能超过未付金额'))
        }
      }
      return callback()
    },
    // 监听合同弹窗数据请求完成
    handleContractLoadCompleted (data) {
      let disabledArr = []
      data.forEach(item => {
        item.contractAmountRemaining <= 0 && disabledArr.push(item.paymentContractId)
      })
      this.disabledArr = disabledArr
    }
  },
};
</script>

<style lang="scss" scoped>
@import "src/views/wy-operate/css/operate.scss";
.addDialog {
  /deep/ .el-dialog__body {
    padding: 16px 32px;
  }
}
</style>
